﻿using S7PlcDataCollector.Models;
using S7PlcWrapper;

namespace S7PlcDataCollector.Service.PlcLink
{
    internal class PlcLinkEntity : IPlcLinkObserver, IPlcDataObserver
    {
        public S7PlcEntity PlcEntity { get; }
        public PlcLinkState LinkState => _plcLinkHelper.LinkState;

        private readonly S7PlcHelper _plcHelper;
        private readonly PlcLinkHelper _plcLinkHelper;
        private readonly PlcDataHelper _plcDataHelper;
        private readonly IPlcLinkObserver _plcLinkObserver;
        private readonly IPlcDataObserver _plcDataObserver;

        public PlcLinkEntity(S7PlcEntity plcEntity, IPlcLinkObserver plcLinkObserver, IPlcDataObserver plcDataObserver)
        {
            PlcEntity = plcEntity;
            _plcLinkObserver = plcLinkObserver;
            _plcDataObserver = plcDataObserver;

            _plcHelper = new S7PlcHelper();
            _plcLinkHelper = new PlcLinkHelper(PlcEntity, _plcHelper, this);
            _plcDataHelper = new PlcDataHelper(_plcHelper, this);
        }

        public void Init()
        {
            _plcHelper.Init(PlcEntity.TypeEnum, PlcEntity.Ip, PlcEntity.Port, PlcEntity.Rack, PlcEntity.Slot);
            _plcLinkHelper.Start();
            _plcDataHelper.Start();
        }

        public void UnInit()
        {
            _plcDataHelper.Stop();
            _plcLinkHelper.Stop();
            _plcHelper.UnInit();
        }

        public void GetVariable(S7PlcVariableEntity variableEntity)
        {
            _plcDataHelper.AddVariable(variableEntity);
        }

        public void LinkStateChange(S7PlcEntity plcEntity, PlcLinkState linkState)
        {
            _plcLinkObserver?.LinkStateChange(plcEntity, linkState);
        }

        public void ReceivePlcData(S7PlcVariableEntity variableEntity, PlcDataResult result)
        {
            _plcDataObserver?.ReceivePlcData(variableEntity, result);
        }
    }
}
